/**
* Format Bar for Wikindx Word Processor
*
* @author	Mark Tsikanovski (additional work:  Mark Grimshaw)
* @version	1
*
* Includes a modified version of code from the Rich Text Editor by Kevin Roth (modification by Mark Grimshaw & Mark Tsikanovski)
* Cross-Browser Rich Text Editor
* http://www.kevinroth.com/rte/demo.htm
* Written by Kevin Roth (kevin@NOSPAMkevinroth.com - remove NOSPAM)
* Visit the support forums at http://www.kevinroth.com/forums/index.php?c=2
*(This code is public domain. Redistribution and use of this code, with or without modification, is permitted.)
*/

function mouseOverImageButton(buttonId, mouseState) {
	if (mouseState == 1) {
		document.getElementById(buttonId).style.backgroundColor=buttonMouseOverColor;
	}
	else {
		var oRTE = document.getElementById(rte).contentWindow;
		if(((buttonId == 'bold') || (buttonId == 'italic') || (buttonId == 'underline') ||
			(buttonId == 'justifycenter') || (buttonId == 'justifyfull') || (buttonId == 'justifyright') || 
			(buttonId == 'justifyleft') || (buttonId == 'subscript') || (buttonId == 'superscript'))
			&& oRTE.document.queryCommandState(buttonId))
			document.getElementById(buttonId).style.backgroundColor=buttonMouseDownColor;
		else
			document.getElementById(buttonId).style.backgroundColor=buttonBaseColor;
	}	
}

function mouseDownImageButton(buttonId, mouseState) {
	if (mouseState == 1) {
		document.getElementById(buttonId).style.backgroundColor=buttonMouseDownColor;
		document.getElementById(buttonId).style.border="inset 2px #c0c0c0";
	}
	else {
		document.getElementById(buttonId).style.backgroundColor=buttonMouseOverColor;
		document.getElementById(buttonId).style.border="outset 2px #c0c0c0";
	}	
}

//global RTE stuff
var rte = 'paperText';
var isRichText = false;
var includesPath = 'core/wp/JsFormatBar/';
var generateXHTML;
var readOnly = false;
var directCmd = false;
var currentRTE;
var allRTEs = "";
var css;
var rngStartContainer;
var rngStartOffset;
var rngEndContainer;
var rngEndOffset;
var browserWidth;
var browserHeight;
var paperStatusMessage; // set externally in WP.php
var iframeMessageSet = false;
var environmentSet = false;
var formatIndicatorFont = "Times New Roman";
var formatIndicatorSize = "3";
var formatIndicatorColor = "black";
var specialEdit;
var storeFind;
var storeFindRegExpHighlighted = false;
var storeFindRegExp = false;
var storeLastFindPosition;
var paperInitialized = false;

var agt=navigator.userAgent.toLowerCase();
var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
                && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
var is_opera = (agt.indexOf("opera") != -1);
var is_win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
var is_mac    = (agt.indexOf("mac")!=-1);
var is_safari = (agt.indexOf("safari") != -1);
var is_konqueror = (agt.indexOf("konqueror") != -1);
var is_gecko = (agt.indexOf("gecko") != -1);


/**
* Open pop-up append paper window in the SUWP
*/
function openAppendPaperWindow(url){
 browserDimensions();
 var w = browserWidth * 0.5;
 var h = browserHeight * 0.75;
 var appendWindow = window.open(url,'winAppend','height=' + h + 
	',width=' + w + ',left=10,top=10,status,scrollbars,resizable,dependent');
}

// Init append paper
function handleAppendPaperFormRte(e)
{
	var appendPaperString = getAppendPaperStringRte();
	return appendPaperString;
}

// Append paper string
function getAppendPaperStringRte()
{
 var hidden = document.forms['js']['appendPaperText'];
 return hidden.value; // data has been encoded with PHP's rawurlencode()
}

// Append paper -- add a section break?
function handleAppendSectionFormRte(e)
{
	var section = document.forms['js']['appendSection'];
	if((section.type == "checkbox") && section.checked)
		return '<hr>';
	else
		return '<br>';
}

function appendPaperRte(appendPaperString, section)
{
	currentRTE = rte;
	var oldString = document.getElementById(rte).contentWindow.document.body.innerHTML;
	var newString = oldString + section + unescape(appendPaperString);
// select all and remove old HTML then insert new HTML
	rteSelect(rte, 'selectall', null);
	rteCommand(rte, 'delete', null);
	insertHTML(newString);
}

// Init metadata insertion
function handleMetadataFormRte(e)
{
	if(isValidMetadataFormRte(e)) // validate that cite data exists
	{
		var metadataString = getMetadataStringRte();
		return metadataString;
	}
}

// Insert metadata string
function getMetadataStringRte()
{
	var hidden = document.forms['js']['hidden_' + radioId];
	var citeTagOnly = document.forms['js']['citeTagOnly'];
	if((citeTagOnly.type == "checkbox") && citeTagOnly.checked) // insert only the cite tag
	{
		var hiddenCiteTag = document.forms['js']['hiddenCiteTag_' + radioId];
		if(hiddenCiteTag.value)
			return hiddenCiteTag.value;
	}
	return hidden.value; // data has been encoded with PHP's rawurlencode()
}

function isValidMetadataFormRte(e){
 // check input
 var radio = document.forms['js']['cite'];
 var item = 0;
 if (typeof radio.length == "undefined") {
   radioId = document.getElementById('cite').value;
   return true;
 }
 else {
	 while (item < radio.length) {
			if (radio[item].checked) {
	//      alert('You picked item number:: ' + radio[item].value);
			radioId = radio[item].value;
			return true;
				}
				item++;
			}
	 return false;
	}
}

function insertMetadataRte(metadataString)
{
	currentRTE = rte;
	insertHTML(metadataString);
}

// Init cite tags insertion
function handleCiteFormRte(e)
{
//currentRTE = rte;
//insertHTML('citeString');
	if(isValidCiteFormRte(e)) // validate that cite data exists
	{
		var citeString = getCiteStringRte();
		return citeString;
	}
}

function isValidCiteFormRte(e)
{
 var citeSelect = document.forms['js']['cite'];
	if((typeof citeSelect.length == "undefined" && citeSelect.checked) || citeSelect.length > 0)
		return true;
	return false;
}

// Insert citation string
function getCiteStringRte()
{
 var radio = document.forms['js']['cite'];
 var item = 0;
 if (typeof radio.length == "undefined")
   var citeSelect = document.getElementById('cite').value;
   else
   {
 while (item < radio.length) {
		if (radio[item].checked) {
//      alert('You picked item number:: ' + radio[item].value);
		var citeSelect = radio[item].value;
		break;
			}
			item++;
		}
	}
 var pageStart = document.forms['js'].elements['pageStart'];
 var pageEnd = document.forms['js'].elements['pageEnd'];
 var preText = document.forms['js'].elements['preText'];
 var postText = document.forms['js'].elements['postText'];
 var citeString = ' [cite]' + citeSelect; // resource Id
 if (pageStart.value.length > 0){ // page start exists
  citeString += ':' + pageStart.value;
  if (pageEnd.value.length > 0){ // page end exists
   citeString += '-' + pageEnd.value;
  }
 }
 else if (pageEnd.value.length > 0){ // no page start, but page end exists so force to pageStart
  citeString += ':' + pageEnd.value;
 }
 if (preText.value.length > 0){ // preText exists
  citeString += '|' + preText.value;
  if (postText.value.length > 0){ // && postText exists
   citeString += '`' + postText.value;
  }
 }
 else if(postText.value.length > 0){ // postText exists but no preText
   citeString += '|`' + postText.value;
  }
 citeString += '[/cite]';
 return citeString;
}

function insertCiteStringRte(citeString)
{
	currentRTE = rte;
	insertHTML(citeString);
}

// Insert a timestamp - system default format
function timestamp() {
//  if (!textInput) {
 //   return;
 // }
//  textInput.focus();
//  textInput.value += today.toString();
  var today = new Date();
	currentRTE = rte;
	insertHTML(today);
}

function calendar() {
	currentRTE = rte;
	popUpWin(includesPath + 'calendar.php', 'Calendar', 190, 160, '');	
//	popUpWin(includesPath + 'calendar.php', 'Calendar', 500, 500, '');	
}

function insertDateStringRte(dateString)
{
	currentRTE = rte;
	insertHTML(dateString);
}

// Provide some basic statistics on what's typed
function stats(rte) {
	var justText;
	var pageCount = false;
	justText = document.getElementById(rte).contentWindow.document.body.innerHTML;
// trim
	justText = trim(justText);
// Remove all citation tags
	justText = justText.replace(/\[cite\].*?\[\/cite\]/g, '');
//alert(justText);
// Handle paragraphs first - different browsers do different things for HTML in design mode!
// blank paragraphs in FF and IE come in as '<p>&nbsp;</p>' -- remove them in addition to newline characters
// sometimes the blank paragraphs come in as <p><br></p>....
	justText = justText.replace(/\r\n|\n|\r/g, "__WIKINDX__WORDBREAK__");
	justText = justText.replace(/\r|\n|<p>&nbsp;<\/p>|<p>\s*<br>\s*<\/p>/ig, '');
//alert(justText);
// Since browser implementation of paragraphs is so variable, we don't bother counting no. of paragraphs.
// Keeping code just in case we manage to sort it out...
/*
	var pc = justText.match(/<p.*?>.*?<\/p>|<br><br>.*?<br>/ig);
	var paragraphCount = 0;
	if(pc != null)
	{
		var pcCount = '';
		for(var i = 0; i < pc.length; i++)
		{
			if(pc[i] != '')
				++paragraphCount;
			pcCount += "pc: " + pc[i] + "\n";
		}
alert(pcCount);
	}
*/
// Remove all paragraph tags and prepend &nbsp; to start of paragraph text to ensure that we have a word break here
	justText = justText.replace(/<p.*?>(.*?)<\/p>|(<br>\s*){2}/ig, "__WIKINDX__WORDBREAK__$1");
// Ensure we have no __WIKINDX__WORDBREAK__ at either the bigninning or the end of the text
	justText = justText.replace(/^__WIKINDX__WORDBREAK__|__WIKINDX__WORDBREAK__$/g, "");
// remove HTML code
//	justText = justText.replace(/(<([^>]+)>)/ig,"");
	justText = justText.replace(/<.*?>|<\/.*?>|<.*?>(.*?)<\/.*?>/g, "$1");
// user entered extra space is &nbsp; (i.e. more than one space in sequence) - any other space not between user text is 
// browser-specific and related to the HTML code so remove it.
// Replace single whitespace with &nbsp; and remove all other space
	justText = justText.replace(/\s{1,1}/g, "&nbsp;");
	justText = justText.replace(/\s/g, '');
// trim again
	justText = trim(justText);
	if(justText == '')
	{
		alert("Nothing to count");
		return;
	}
	var justTextFt = justText;
// Replace all footnote and endnote tags with single space
	justText = justText.replace(/\[footnote\].*?\[\/footnote\]/g, ' ');
//alert(justText);
// We now have text in a format suitable for parsing into words, characters etc.  NB - any string enclosed by &...; is a single character
// Count &nbsp; as whitespace
	var whitespace = justText.match(/&nbsp;|__WIKINDX__WORDBREAK__/g);
	if(whitespace == null)
		whitespace = 0;
	else
		whitespace = whitespace.length;
// Non IE browsers always add one extra space somewhere
	if(!is_ie && (whitespace > 0))
		--whitespace;
// Count words - words is loosely defined...
	var wc = justText.split(/&nbsp;{1}|__WIKINDX__WORDBREAK__/g);
	var wordCount = 0;
	for(var i = 0; i < wc.length; i++)
	{
		if(wc[i] != '')
			++wordCount;
	}
	var wc = justTextFt.split(/&nbsp;{1}|__WIKINDX__WORDBREAK__|\[footnote\]|\[\/footnote\]/g);
	var wordCountFt = 0;
	for(var i = 0; i < wc.length; i++)
	{
		if(wc[i] != '')
			++wordCountFt;
	}
// Count no. lines in order to estimate no. pages @ 40 lines/page and 15 words/line.  Create page count if lineCount > 1000
	if(wordCount > 1000)
		pageCount = Math.round(wordCount/(40 * 15));
// remove all &nbsp; whitespace and temporary wordbreak chars
	justText = justText.replace(/&nbsp;|__WIKINDX__WORDBREAK__/g, '');
// now replace all &...; chars with single character `
	justText = justText.replace(/&.*?;/g, '`');
//alert(justText);
// count punctuation then remove -- keep to grammatical punctuation
	var punctuation = justText.match(/[\.,\:;\?\!`'"]/g);
	if(punctuation == null)
		punctuation = 0;
	else
		punctuation = punctuation.length;
//alert(punctuation);
	justText = justText.replace(/[\.,\:;\?\!`'"]/g, '');
//alert(justText);
// Now count all characters remaining
	var charCountEx = justText.length;
//alert(charCountEx);
// Total of all characters excluding whitespace but including punctuation
	var charCountIn = charCountEx + punctuation;
// Total of all characters
	var charCountAll = charCountIn + whitespace;
//alert(charCountAll);
//	if(paragraphCount == 0)
//		paragraphCount = 1;
	var punctuationString = ". , : ; ` ' \" ! ? " + "\n";
	if(charCountEx == 0)
		alert("Nothing to count");
	else if(pageCount)
		alert("Character Count (excluding punctuation & space) = " + charCountEx + "\n" +
			"Character Count (including punctuation excluding space) = " + charCountIn + "\n" +
			"Character Count (including punctuation & space) = " + charCountAll + "\n" +
			"Word Count (excluding cite tags and footnotes) = " + wordCount + "\n" +			
			"Word Count (excluding cite tags) = " + wordCountFt + "\n" +					
			"Approximate Page Count = " + pageCount + " @40 lines/page, 15 words/line\n" +
			"\nPunctuation is: . , : ; ` ' \" ! ? \n"
			);
	else
		alert("Character Count (excluding punctuation & space) = " + charCountEx + "\n" +
			"Character Count (including punctuation excluding space) = " + charCountIn + "\n" +
			"Character Count (including punctuation & space) = " + charCountAll + "\n" +
			"Word Count (excluding cite tags and footnotes) = " + wordCount + "\n" +				
			"Word Count (excluding cite tags) = " + wordCountFt + "\n" +				
			"\nPunctuation is: . , : ; ` ' \" ! ? \n"
			);

}

function saveDocument() {
	if (document.getElementsByName("fileName").length > 0) {
		updateRTE("paperText");
		form.submit();
		return;
//		alert(document.getElementsByName("fileName")[0].value);
	}
}

function saveDocumentTimer(minutes) {
	saveDocumentID = setInterval("saveDocument()", (minutes * 60000));
}

// enable design mode for WYSIWYG editor
function enableDesignMode(rte, html, css, readOnly) {
// Mark G. double quotes in 'html' come in as &#34; -- need to reset back to normal double quotes or else images, URLs etc. are not correct.
	var newString = html.replace(/&#34;/g, '"');
	html = newString;
	var frameHtml = "<html id=\"" + rte + "\">\n";
	frameHtml += "<head>\n";
	frameHtml += "<link rel=\"stylesheet\" href=\"" + css + "\" type=\"text/css\" />";
//	frameHtml += "<style>\n";
	frameHtml += "</head>\n";
	frameHtml += "<body class=\"suwpInner\">\n";
//	frameHtml += "	background: #FFFFFF;\n";
//	frameHtml += "	margin: 0px;\n";
//	frameHtml += "	padding: 10px;\n";
//	frameHtml += "\n";
//	frameHtml += "</style>\n";
	frameHtml += html + "\n";
	frameHtml += "</body>\n";
	frameHtml += "</html>";
	
	var oRTE = document.getElementById(rte).contentWindow.document;
	if (!is_ie && !readOnly) oRTE.designMode = "On";
	oRTE.styleWithCSS = true;
	oRTE.open();
	oRTE.write(frameHtml);
	oRTE.close();
	if (is_ie && !readOnly) oRTE.designMode = "On";

	if (is_ie) {
		document.getElementById(rte).contentWindow.document.attachEvent("onkeypress", ieKeyPress);
	} else {
		oRTE.addEventListener("keypress", geckoKeyPress, true);
		oRTE.addEventListener("mousedown", geckoMouseDown, true);
	}
	setEnvironment(rte);
	paperInitialized = true;
}

// Reset message field (paper status) in parent window
function resetMessageCell()
{
//	var oRTE = document.getElementById(rte).contentWindow;
//alert(oRTE.document.queryCommandValue('fontname'));
// forecolor
//fontsize
	if(!iframeMessageSet)
	{
		var messageCell = document.getElementById("suwpMessage");
		messageCell.innerHTML = paperStatusMessage;
		if(document.getElementById('nav') == "defined")
		{
			document.getElementById('nav').style.visibility = "hidden";
			document.getElementById('menuRestore').style.visibility = "visible";
		}
		iframeMessageSet = true;
	}
}

// Set up default environment when first launching SUWP
function setEnvironment(rte)
{
// Default font formatting
	if(!environmentSet)
	{
		rteCommand(rte, 'fontname', 'Times New Roman');
		rteCommand(rte, 'fontsize', '3'); // 12 pica
		rteCommand(rte, 'forecolor', ' black');
		rteCommand(rte, 'justifyfull', '');
		environmentSet = true;
	}
}
// Maintain state of font formatting options in the format bar
function resetFormatIndicator()
{
	var oRTE = document.getElementById(rte).contentWindow;
	
	if(oRTE.document.queryCommandState('bold'))
		mouseDownImageButton('bold', 1);
	else
	{
		mouseDownImageButton('bold', 0);
		mouseOverImageButton('bold', 0);
	}
	if(oRTE.document.queryCommandState('italic'))
		mouseDownImageButton('italic', 1);
	else
	{
		mouseDownImageButton('italic', 0);
		mouseOverImageButton('italic', 0);
	}
	if(oRTE.document.queryCommandState('underline'))
		mouseDownImageButton('underline', 1);
	else
	{
		mouseDownImageButton('underline', 0);
		mouseOverImageButton('underline', 0);
	}
	if(oRTE.document.queryCommandState('justifycenter'))
		mouseDownImageButton('justifycenter', 1);
	else
	{
		mouseDownImageButton('justifycenter', 0);
		mouseOverImageButton('justifycenter', 0);
	}
	if(oRTE.document.queryCommandState('justifyleft'))
		mouseDownImageButton('justifyleft', 1);
	else
	{
		mouseDownImageButton('justifyleft', 0);
		mouseOverImageButton('justifyleft', 0);
	}
	if(oRTE.document.queryCommandState('justifyright'))
		mouseDownImageButton('justifyright', 1);
	else
	{
		mouseDownImageButton('justifyright', 0);
		mouseOverImageButton('justifyright', 0);
	}
	if(oRTE.document.queryCommandState('justifyfull'))
		mouseDownImageButton('justifyfull', 1);
	else
	{
		mouseDownImageButton('justifyfull', 0);
		mouseOverImageButton('justifyfull', 0);
	}
	if(oRTE.document.queryCommandState('subscript'))
		mouseDownImageButton('subscript', 1);
	else
	{
		mouseDownImageButton('subscript', 0);
		mouseOverImageButton('subscript', 0);
	}
	if(oRTE.document.queryCommandState('superscript'))
		mouseDownImageButton('superscript', 1);
	else
	{
		mouseDownImageButton('superscript', 0);
		mouseOverImageButton('superscript', 0);
	}
	var fontsize = oRTE.document.queryCommandValue('fontsize');
	var fontname = oRTE.document.queryCommandValue('fontname');
	var forecolor = oRTE.document.queryCommandValue('forecolor');
/*
	else if(!formatIndicatorItalic && (command == 'italic'))
	{
		mouseDownImageButton('italic', 1);
		formatIndicatorItalic = true;
	}
	else if (command == 'italic')
	{
		mouseDownImageButton('italic', 0);
		formatIndicatorItalic = false;
	}
	else if(!formatIndicatorUnderline && (command == 'underline'))
	{
		mouseDownImageButton('underline', 1);
		formatIndicatorUnderline = true;
	}
	else if (command == 'underline')
	{
		mouseDownImageButton('underline', 0);
		formatIndicatorUnderline = false;
	}
	else if (command == 'fontname')
		formatIndicatorFont = option;
	else if (command == 'fontsize')
		formatIndicatorSize = option;
	else if (command == 'forecolor')
		formatIndicatorColor = option;
*/
}

function rteCommand(rte, command, option) {
//function to perform command
	if(paperInitialized)
		resetMessageCell();
	var oRTE;
	oRTE = document.getElementById(rte).contentWindow;
	
	try {
		oRTE.focus();
	  	oRTE.document.execCommand(command, false, option);
		oRTE.focus();
	} catch (e) {
//		alert(e);
//		setTimeout("rteCommand('" + rte + "', '" + command + "', '" + option + "');", 10);
	}
	if (is_ie) {
		oRTE.document.selection.empty();	
	}
	else {
		oRTE.getSelection().collapseToEnd();
	}
	if(environmentSet)
		resetFormatIndicator();
}

// Special function (used in find/replace and cleanupSUWP()  etc.) to select the whole of the rte text without automatically deselecting as 
// would happen with rteCommand() above
function rteSelect(rte, command, option) {
//	resetMessageCell();
	var oRTE;
	oRTE = document.getElementById(rte).contentWindow;
	
	try {
		oRTE.focus();
	  	oRTE.document.execCommand(command, false, option);
		oRTE.focus();
	} catch (e) {
//		alert(e);
//		setTimeout("rteCommand('" + rte + "', '" + command + "', '" + option + "');", 10);
	}
}

// Generic function to set the value of a select option
// Modified Mark Grimshaw
function setOption(rte, selectname, directCmd)
{
	resetMessageCell();
/*
// Attempt fix for transposing lines problem
		specialEdit = "cleanSpans";
		currentRTE = rte;
//get currently highlighted text
		setRange(rte);
		if (is_ie) {
			text = rng.htmlText;
			text = text.replace(/<\/span> /gi, " </span>");
			insertHTML(text);	
		}
		else
		{
			textFragment = rng.extractContents();
			newTextFragment = mozInnerHTML(textFragment);
			newRng = sel.getRangeAt(0);
			newRng.insertNode(newTextFragment);
			newRng.commonAncestorContainer.parentNode.normalize();
//			sel.removeAllRanges();
		}
		specialEdit = "";
// End fix for transposing lines problem
*/
	var idx = document.getElementById(selectname).selectedIndex;
// First one is always a label
	if (idx != 0)
	{
		if(directCmd == false)
		{
			var selected = document.getElementById(selectname).options[idx].value;
			var cmd = selectname.replace('_' + rte, '');
		}
		else
		{
			var cmd = document.getElementById(selectname).options[idx].value;
			var selected = '';
		}
//var messageCell = document.getElementById("formatIndicator");
//messageCell.innerHTML = cmd + ' : ' + selected;;
		rteCommand(rte, cmd, selected);
		document.getElementById(selectname).selectedIndex = 0;
	}
}

// Bring hidden field 'hdnpaperText' in sync with 'paperText' iFrame and generate the HTML code
function updateRTE(rte) {
//set hidden form field value for current rte
	var oHdnField = document.getElementById('hdn' + rte);
	if (oHdnField.value == null) oHdnField.value = "";
		oHdnField.value = document.getElementById(rte).contentWindow.document.body.innerHTML;
//if there is no content (other than formatting) set value to nothing
	if (stripHTML(oHdnField.value.replace("&nbsp;", " ")) == "" &&
		oHdnField.value.toLowerCase().search("<hr") == -1 &&
		oHdnField.value.toLowerCase().search("<img") == -1)
	{
		oHdnField.value = "";
	}
}

// Clean up source HTML code
function cleanupSUWP(rte) {
	currentRTE = rte;
	var oldString;
	var newString;
	oldString = document.getElementById(rte).contentWindow.document.body.innerHTML;
// Convert multiple whitespace characters to one
	newString = oldString.replace(/ {2}/g, ' ');
// Attempt to fix transposing line problem when </span> has a \s after it but not before it (excepting &nbsp;).
// This is a temporary fix until a more permanent one can be found using javascript.
	newString = newString.replace(/<\/span> /ig, " </span>");
// select all and remove old HTML then insert new HTML
	rteSelect(rte, 'selectall', null);
	rteCommand(rte, 'delete', null);
	insertHTML(newString);
}

// Bring hidden field 'hdnpaperText' in sync with 'paperText' iFrame and generate the HTML code.
// To be used from the SAVE pop up where the rte is in the parent/opener window
function updateRTESave(rte, message) {
//set hidden form field value for current rte
	parent.window.opener.iframeMessageSet = false;
	var oHdnField = document.getElementById('hdn' + rte);
	if (oHdnField.value == null)
		oHdnField.value = "";
	oHdnField.value = window.opener.document.getElementById(rte).contentWindow.document.body.innerHTML;
//if there is no content (other than formatting) set value to nothing
	if (stripHTML(oHdnField.value.replace("&nbsp;", " ")) == "" &&
		oHdnField.value.toLowerCase().search("<hr") == -1 &&
		oHdnField.value.toLowerCase().search("<img") == -1)
	{
		oHdnField.value = "";
	}
// Set success message in parent window
	var messageCell = window.opener.document.getElementById("suwpMessage");
	messageCell.innerHTML = message;	
	if(document.getElementById('nav') == "defined")
	{
		window.opener.document.getElementById('nav').style.visibility = "visible";
		window.opener.document.getElementById('menuRestore').style.visibility = "hidden";
	}
// Clear export file hyperlink field in parent window
	var fileCell = window.opener.document.getElementById("exportFile");
	fileCell.innerHTML = '';
}

function menuRestore() {
	document.getElementById('nav').style.visibility = "visible";
	document.getElementById('menuRestore').style.visibility = "hidden";
	iframeMessageSet = false;
}

function stripHTML(oldString) {
//function to strip all html
	var newString = oldString.replace(/(<([^>]+)>)/ig,"");
	
//replace carriage returns and line feeds
   newString = newString.replace(/\r\n/g," ");
   newString = newString.replace(/\n/g," ");
   newString = newString.replace(/\r/g," ");
	
//trim string
	newString = trim(newString);
	
	return newString;
}

function setRange(rte) {
//function to store range  and associated range boundary info of current selection
	var oRTE = document.getElementById(rte).contentWindow;
	if (is_ie) {
		rng = oRTE.document.selection.createRange();
	} else {
		sel = oRTE.getSelection();
		rng = sel.getRangeAt(0);
		node = sel.getRangeAt(0).commonAncestorContainer;
		rngStartContainer = rng.startContainer;
		rngStartOffset = rng.startOffset;
		rngEndContainer = rng.endContainer;
		rngEndOffset = rng.EndOffset;
	}
	return rng;
}

function trim(inputString) {
// Removes leading and trailing spaces from the passed string. Also removes
// consecutive spaces and replaces it with one space. If something besides
// a string is passed in (null, custom object, etc.) then return the input.
   if (typeof inputString != "string") return inputString;
   var retValue = inputString;
   var ch = retValue.substring(0, 1);
	
   while (ch == " ") { // Check for spaces at the beginning of the string
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length - 1, retValue.length);
	
   while (ch == " ") { // Check for spaces at the end of the string
      retValue = retValue.substring(0, retValue.length - 1);
      ch = retValue.substring(retValue.length - 1, retValue.length);
   }
	
	// Note that there are two spaces in the string - look for multiple spaces within the string
   while (retValue.indexOf("  ") != -1) {
		// Again, there are two spaces in each of the strings
      retValue = retValue.substring(0, retValue.indexOf("  ")) + 
		retValue.substring(retValue.indexOf("  ") + 1, retValue.length);
   }
   return retValue; // Return the trimmed string back to the user
}

function dlgInsertTable(rte, command) {
	//function to open/close insert table dialog
	//save current values
	parent.command = command;
	currentRTE = rte;
	InsertTable = popUpWin(includesPath + 'insert_table.htm', 'InsertTable', 360, 180, '');
}

function dlgFindReplace(rte, command) {
	//function to find and replace text dialog
	//save current values
	parent.command = command;
	currentRTE = rte;
	FindReplace = popUpWin(includesPath + 'findReplace.htm', 'FindReplace', 360, 180, '');
}

/**
Handle find and replace on whole paper
*/
function findReplace(rte, find, replace, caseSensitive, wholeWord)
{
	text = document.getElementById(rte).contentWindow.document.body.innerHTML;
/*
	alert(text);
	alert(find);
	alert(replace);
	alert(caseSensitive);
*/
	if(caseSensitive == 'on')
	{
		if(wholeWord == 'on')
			var regExp = new RegExp("\\b" + find + "\\b", 'g');
		else
			var regExp = new RegExp(find, 'g');
	}
	else // case-insensitive
	{
		if(wholeWord == 'on')
			var regExp = new RegExp("\\b" + find + "\\b", 'ig');
		else
			var regExp = new RegExp(find, 'ig');
	}
	text = text.replace(regExp, replace);
	rteSelect(rte, 'selectall', null);
	rteCommand(rte, 'delete', null);
	insertHTML(text);
}

function dlgFind(rte, command) {
	//function to find and replace text dialog
	//save current values
	parent.command = command;
	currentRTE = rte;
	Find = popUpWin(includesPath + 'find.htm', 'Find', 360, 180, '');
}

/**
Handle find on whole paper
*/
function findText(rte, find, caseSensitive, wholeWord, findType)
{
	text = document.getElementById(rte).contentWindow.document.body.innerHTML;
	if (findType == 'all') {
		if(caseSensitive == 'on')
		{
			if(wholeWord == 'on') {
				var regExp = new RegExp("\\b" + find + "\\b", 'g');
			}
			else {
				var regExp = new RegExp(find, 'g');
			}
		}
		else // case-insensitive
		{
			if(wholeWord == 'on') {
				var regExp = new RegExp("\\b" + find + "\\b", 'ig');
			}
			else {
				var regExp = new RegExp(find, 'ig');
			}
		}
	}
	else { // first occurence
		if(caseSensitive == 'on')
		{
			if(wholeWord == 'on') {
				var regExp = new RegExp("\\b" + find + "\\b");
			}
			else {
				var regExp = new RegExp(find);
			}
		}
		else // case-insensitive
		{
			if(wholeWord == 'on') {
				var regExp = new RegExp("\\b" + find + "\\b", 'i');
			}
			else {
				var regExp = new RegExp(find, 'i');
			}
		}	
	}
	var position;
// un-highlight previous highlighted find
	text = text.replace(storeFindRegExpHighlighted, storeFind);
	rteSelect(rte, 'selectall', null);
	rteCommand(rte, 'delete', null);
	insertHTML(text);	
	if((position = text.search(regExp)) != -1)
	{
		findHighlighted = '<span style\\="background-color\\: yellow[;]?">' + find + '<\\/span>';
		var regExpHighlighted = new RegExp(findHighlighted, 'ig');	
		document.getElementById(rte).selectionStart = position;
		document.getElementById(rte).selectionEnd = position + find.length;

// highlight new find		
		replace = '<span style\="background-color\: yellow;">' + find + '<\/span>';		
		text = text.replace(regExp, replace);
		rteSelect(rte, 'selectall', null);
		rteCommand(rte, 'delete', null);
		insertHTML(text);		
	}
// Store values for findTextAgain
	storeFind = find;
	storeFindRegExpHighlighted = regExpHighlighted;
	storeFindRegExp = regExp;
	storeLastFindPosition = position;
}
/**
Handle find again on whole paper (Not yet coded)
*/
function findTextAgain(rte)
{
	text = document.getElementById(rte).contentWindow.document.body.innerHTML;
	var position;
	if((position = text.search(storeFindRegExp)) != -1)
		alert(position);
	document.getElementById(rte).selectionStart = position;
	document.getElementById(rte).selectionEnd = position + find.length;
}

function dlgInsertLink(rte, command) {
//function to insert hyperlink dialog
//save current values
	parent.command = command;
	currentRTE = rte;
	InsertLink = popUpWin(includesPath + 'insert_link.htm', 'InsertLink', 360, 180, '');
	
//get currently highlighted text and set link text value
	setRange(rte);
	var linkText = '';
	if (is_ie) {
		linkText = stripHTML(rng.htmlText);
	} else {
		linkText = stripHTML(rng.toString());
	}
	setLinkText(linkText);
}

// Convert selected text to Uppercase
function upperCase(rte)
{
	specialEdit = "toUpperCase";
	resetMessageCell();
	currentRTE = rte;
//get currently highlighted text
	setRange(rte);
	var text;
	if (is_ie) {
		text = rng.htmlText;
//		text = text.replace(/<(.*?)p>/ig, '<$1__WIKINDX__TEMP__P__REPLACE__>');
		text = text.toUpperCase();
//		text = text.replace(/<(.*?)__WIKINDX__TEMP__P__REPLACE__>/g, '<$1P>');
		text = text.replace(/\[(.*?)CITE\]/g, '[$1cite]');
		text = text.replace(/\[(.*?)FOOTNOTE\]/g, '[$1footnote]');
		text = text.replace(/&NBSP;/g, '&nbsp;');
		insertHTML(text);	
	}
	else
	{
		textFragment = rng.extractContents();
		newTextFragment = mozInnerHTML(textFragment);
		newRng = sel.getRangeAt(0);
		newRng.insertNode(newTextFragment);
//		newRng.commonAncestorContainer.parentNode.normalize();
		sel.collapseToEnd();
	}
	specialEdit = "";
}

// Convert selected text to Lowercase
function lowerCase(rte)
{
	specialEdit = "toLowerCase";
	resetMessageCell();
	currentRTE = rte;
//get currently highlighted text
	setRange(rte);
	var text;
	if (is_ie) {
		text = rng.htmlText;
		text = text.toLowerCase();
		insertHTML(text);
	}
	else
	{
		textFragment = rng.extractContents();
		newTextFragment = mozInnerHTML(textFragment);
		newRng = sel.getRangeAt(0);
		newRng.insertNode(newTextFragment);
//		newRng.commonAncestorContainer.parentNode.normalize();
		sel.collapseToEnd();
	}
	specialEdit = ""	
}

// Insert section break
function insertSection(rte)
{
	specialEdit = "insertSection";
	resetMessageCell();
	currentRTE = rte;
	var text = "<hr>";
	insertHTML(text);
	specialEdit = ""	
}
function setLinkText(linkText) {
	resetMessageCell();
//set link text value in insert link dialog
	try {
		window.InsertLink.document.linkForm.linkText.value = linkText;
	} catch (e) {
//may take some time to create dialog window.
//Keep looping until able to set.
		setTimeout("setLinkText('" + linkText + "');", 10);
	}
}

function popUpWin (url, win, width, height, options) {
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	options += 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos;
	return window.open(url, win, options);
}

//function to save and export paper
function openPopUpSaveExportDialogue(filename, databaseID) {
	var options1 = '';
	if(filename)
		options1 = '&filename=' + filename;
	if(databaseID)
		options1 += '&databaseID=' + databaseID;
	browserDimensions();
	var width = browserWidth * 0.9;
	var height = browserHeight * 0.8;
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	var options2 = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos + 
		',status,scrollbars,resizable';
	var url = 'index.php?action=wpSaveExportDialogue' + options1;
	return window.open(url, 'saveDialogue', options2);
}

//function to save paper
function openPopUpSaveDialogue(filename, databaseID) {
	var options1 = '';
	if(filename)
		options1 = '&filename=' + filename;
	if(databaseID)
		options1 += '&databaseID=' + databaseID;
	browserDimensions();
	var width = browserWidth * 0.5;
	var height = browserHeight * 0.2;
	var url = 'index.php?action=wpSaveDialogue' + options1;
	var leftPos = (screen.availWidth - width) / 2;
	var topPos = (screen.availHeight - height) / 2;
	var options2 = 'width=' + width + ',height=' + height + ',left=' + leftPos + ',top=' + topPos + 
		',status,scrollbars,resizable';
	return window.open(url, 'saveDialogue', options2);
}

function addImage(rte) {
//function to add image
	imagePath = prompt('Enter Image URL:', 'http://');				
	if ((imagePath != null) && (imagePath != ""))
	{
// Image must be a URL on a valid web server.  If only a path is given, prepend http://localhost
		if(imagePath.match(/^http/) == false)
		{
			if(imagePath.match(/^\//) == true)
				imagePath = 'http://localhost' + imagePath;
			else
				imagePath = 'http://localhost/' + imagePath;
		}
		rteCommand(rte, 'InsertImage', imagePath);
	}
}

function setFootnoteText(text) {
//set text value in insert link dialog
	try {
		window.InsertFootnote.document.footnoteForm.footnote.value = text;
	} catch (e) {
//may take some time to create dialog window.
//Keep looping until able to set.
		setTimeout("setFootnoteText('" + text + "');", 10);
	}
}

function dlgFootnote(rte, command) {
	parent.command = command;
	currentRTE = rte;
	InsertFootnote = popUpWin(includesPath + 'footnoteLoad.htm', 'InsertFootnote', 750, 270, '');
	
//get currently highlighted text and set link text value
	setRange(rte);
	var text = '';
	if (is_ie) {
		text = stripHTML(rng.htmlText);
	} else {
		text = stripHTML(rng.toString());
	}
	setFootnoteText(text);
}

function dlgSpChar(rte, command) {
	parent.command = command;
	currentRTE = rte;
	InsertSpChar = popUpWin(includesPath + 'sp_charLoad.htm', 'InsertSpChar', 750, 270, '');
}

function showHideElement(element, showHide) {
	//function to show or hide elements
	//element variable can be string or object
	if (document.getElementById(element)) {
		element = document.getElementById(element);
	}
	
	if (showHide == "show") {
		element.style.visibility = "visible";
	} else if (showHide == "hide") {
		element.style.visibility = "hidden";
	}
}

// designMode command 'removeFormat' doesn't work in all cases so replace with bespoke function to remove all HTML tags.
// Even this doesn't work with IE which insists on always having <p> tags at the very least.
function removeFormat()
{
	resetMessageCell();
	currentRTE = rte;
//get currently highlighted text
	setRange(rte);
	var oldString;
	if (is_ie) {
		oldString = rng.htmlText;
	} else {
		oldString = rng.toString();
	}
	var newString = oldString.replace(/(<([^>]+)>)/g,"");
	insertHTML(newString);
}

function insertHTML(html) {
//function to add HTML -- thanks dannyuk1982
	resetMessageCell();
	var rte = currentRTE;
	var oRTE = document.getElementById(rte).contentWindow;
	oRTE.focus();
	if (is_ie) {
		oRTE.document.selection.createRange().pasteHTML(html);
	} else {
		oRTE.document.execCommand('inserthtml', false, html);
	}
}

// Ernst de Moor: Fix the amount of digging parents up, in case the RTE editor itself is displayed in a div.
// KJR 11/12/2004 Changed to position palette based on parent div, so palette will always appear in proper location regardless of nested divs
function getOffsetTop(elm) {
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	var parents_up = 2; //the positioning div is 2 elements up the tree
	
	while(parents_up > 0) {
		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
		parents_up--;
	}
	
	return mOffsetTop;
}

// Ernst de Moor: Fix the amount of digging parents up, in case the RTE editor itself is displayed in a div.
// KJR 11/12/2004 Changed to position palette based on parent div, so palette will always appear in proper location regardless of nested divs
function getOffsetLeft(elm) {
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	var parents_up = 2;
	
	while(parents_up > 0) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
		parents_up--;
	}
	
	return mOffsetLeft;
}


// Get browser dimensions.
// Code adapted from http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=16
function browserDimensions()
{
	if( typeof( window.innerWidth ) == 'number' )
	{
//Non-IE
		browserWidth = window.innerWidth;
		browserHeight  = window.innerHeight;
	}
	else if( document.documentElement &&
      ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
	{
//IE 6+ in 'standards compliant mode'
		browserWidth = document.documentElement.clientWidth;
		browserHeight  = document.documentElement.clientHeight;
	}
	else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )
	{
//IE 4 compatible
		browserWidth = document.body.clientWidth;
		browserHeight  = document.body.clientHeight;
	}
// These now set for each template within template.js
//set SUWP document height as appropriate for browser height
//	document.getElementById('paperText').style.width = (browserWidth * 0.8) + "px";
//	document.getElementById('paperText').style.height = (browserHeight * 0.74) + "px";
//	document.getElementById('paperText').style.width = (browserWidth * 0.72) + "px";
	return browserHeight;
}

//********************
//Gecko-Only Functions
//********************
function geckoKeyPress(evt) {
//function to add bold, italic, and underline shortcut commands to gecko RTEs
//contributed by Anti Veeranna (thanks Anti!)
	resetMessageCell();
	var rte = evt.target.id;
	
	if (evt.ctrlKey) {
		var key = String.fromCharCode(evt.charCode).toLowerCase();
		var cmd = '';
		switch (key) {
			case 'b': cmd = "bold"; break;
			case 'i': cmd = "italic"; break;
			case 'u': cmd = "underline"; break;
		};

		if (cmd) {
			rteCommand(rte, cmd, null);
			
// stop the event bubble
			evt.preventDefault();
			evt.stopPropagation();
		}
 	}
	resetFormatIndicator();
}
function geckoMouseDown(evt) {
	resetFormatIndicator();
}

//*****************
//IE-Only Functions
//*****************
function ieKeyPress(evt) {
	resetFormatIndicator();
	return;
	resetMessageCell();
	var key = (evt.which || evt.charCode || evt.keyCode);
	var stringKey = String.fromCharCode(key).toLowerCase();
}

//**********************
//Moz microcontent editing
//thanks to John Udell October 8, 2003
//http://www.xml.com/pub/a/2003/10/08/udell.html
//**********************
function mozInnerHTML(node) {
  for (var i = 0; i < node.childNodes.length; i++) {
		mozOuterHTML(node.childNodes.item(i));
	}
	return node;
}

function mozOuterHTML(node) {
  switch (node.nodeType) {
    case Node.ELEMENT_NODE: 
      for (var i = 0; i < node.attributes.length; i++) {
        var attr = node.attributes.item(i);
//edit 'attr.nodeName' to edit an attribute Name of an element node  e.g. 'style' here
//edit 'attr.nodeValue' to edit an attribute value of an element node  e.g. 'font-weight:bold' here

      }
      if ( !node.hasChildNodes && !node.hasAttributes ) {
//process nodes without child nodes and without attributes here

			}
      else {
//edit innerHTML (mozInnerHTML) here, where the mozInnerHTML(node) is the object e.g. 'HTML span element' and node.nodeName is e.g. 'span'
				mozInnerHTML(node);
      }
      break;
    case Node.TEXT_NODE:
//edit 'node.nodeValue' to edit the value of an text node  i.e the actual text (e.g. make it upper case like 'node.nodeValue = node.nodeValue.toUpperCase();'
			switch (specialEdit) {
				case 'toUpperCase':
					node.nodeValue = node.nodeValue.toUpperCase();
					node.nodeValue = node.nodeValue.replace(/\[(.*?)CITE\]/g, '[$1cite]');
					node.nodeValue = node.nodeValue.replace(/\[(.*?)FOOTNOTE\]/g, '[$1footnote]');
					break;
				case 'toLowerCase':
					node.nodeValue = node.nodeValue.toLowerCase();
					break;
				case 'cleanSpans':
					node.nodeValue = node.nodeValue.replace(/<\/span> /ig, " </span>");
					break;
				default:
					break;
			}
      break;
    default:
			break;
  }
	return node;
}
